import 'package:waimai_flutter_app/components/MainBackground.dart';
import 'package:waimai_flutter_app/components/NavigationPanel.dart';
import 'package:waimai_flutter_app/components/PullUpToRefreshAnimation.dart';
import 'package:waimai_flutter_app/components/RecommendedFoodItem.dart';
import 'package:waimai_flutter_app/components/RestaurantAds.dart';
import 'package:waimai_flutter_app/components/SpecialRecommendation.dart';
import 'package:waimai_flutter_app/components/TopBar.dart';
import 'package:provider/provider.dart';
import 'package:waimai_flutter_app/uitls/ScrollUtils.dart';
import 'components/Carousel.dart';
import 'components/FilterBar.dart';
import 'components/MyBottomNavigationBar.dart';
import 'components/PullDownToRefreshAnimation.dart';
import 'components/SearBox.dart';
import 'components/SearchKeywords.dart';
import 'constants.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:async/async.dart';
import 'package:waimai_flutter_app/models.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ChangeNotifierProvider(
        create: (context) => ScrollState(),
        child: MyHomePage(
          title: "美团外卖， 送啥都快",
        ),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  MyHomePage({Key key, this.title}) : super(key: key);

  @override
  State<StatefulWidget> createState() => MyAppState();
}

class MyAppState extends State<MyHomePage> {
  ScrollController _scrollController;
  ScrollPhysics _scrollPhysicsBouncing;
  NearbyFoods _nearbyFoods;

  @override
  void initState() {
    _scrollController = MyScrollController();
    _scrollController.addListener(() {
      Provider.of<ScrollState>(context, listen: false)
          .update(_scrollController.offset, MediaQuery.of(context).padding.top);
      if (_scrollController.position.maxScrollExtent ==
          _scrollController.offset) {
        _nearbyFoods.loadMore();
      }
    });
    _scrollPhysicsBouncing =
        CustomScrollPhysics(parent: AlwaysScrollableScrollPhysics());
    _nearbyFoods = NearbyFoods();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return AnnotatedRegion<SystemUiOverlayStyle>(
      value: SystemUiOverlayStyle(
        statusBarColor: Colors.transparent,
      ),
      child: Scaffold(
        backgroundColor: Color(0xFFF5F5F5),
        body: Stack(
          children: [
            NotificationListener<Notification>(
              onNotification: (notification) {
                if (notification is ScrollStartNotification) {
                  Provider.of<ScrollState>(context, listen: false)
                      .onScrollStart();
                  return true;
                } else if (notification is ScrollEndNotification) {
                  Provider.of<ScrollState>(context, listen: false)
                      .onScrollEnd();
                  return true;
                }
                return false;
              },
              child: StreamBuilder(
                stream: _nearbyFoods.stream,
                builder: (BuildContext context, AsyncSnapshot _snapshot) {
                  return ListView.builder(
                      controller: _scrollController,
                      padding: const EdgeInsets.all(0),
                      physics: _scrollPhysicsBouncing,
                      itemBuilder: (context, index) {
                        return _getListItem(context, index,
                            _snapshot.hasData ? _snapshot.data : []);
                      });
                },
              ),
            ),
            Consumer<ScrollState>(
              builder: (context, state, child) {
                return Transform.translate(
                  offset: Offset(
                      0, state.scrollOffset < 0 ? -state.scrollOffset : 0),
                  child: const TopBar(),
                );
              },
            ),
            Consumer<ScrollState>(
              builder: (context, state, child) {
                return Transform.translate(
                  offset: Offset(
                      0, state.scrollOffset < 0 ? -state.scrollOffset : 0),
                  child: SearchBox(),
                );
              },
            ),
            Consumer<ScrollState>(
              builder: (context, state, _) {
                return Transform.translate(
                  offset: Offset(
                      0,
                      -topLoadingIconHeight +
                          (state.scrollOffset < 0 ? -state.scrollOffset : 0)),
                  child: Transform.scale(
                    scale: (state.scrollOffset < 0
                        ? ((-state.scrollOffset / topLoadingIconHeight) > 1
                            ? (1)
                            : (-state.scrollOffset / topLoadingIconHeight))
                        : (0)),
                    origin: Offset(0, topLoadingIconHeight / 2),
                    child: PullDownToRefreshAnimation(),
                  ),
                );
              },
            ),
          ],
        ),
        bottomNavigationBar: Theme(
          data: Theme.of(context).copyWith(canvasColor: Colors.transparent),
          child: MyBottomNavigationBar(),
        ),
        floatingActionButton: Consumer<ScrollState>(
          builder: (_, state, __) {
            return AnimatedContainer(
              duration: const Duration(milliseconds: 200),
              transform: Matrix4.identity()..translate(state.fabOffsetX),
              child: AnimatedOpacity(
                duration: Duration(milliseconds: 200),
                opacity: state.fabOpacity,
                child: FloatingActionButton(
                  mini: true,
                  backgroundColor: Colors.white,
                  onPressed: () {},
                  child: Image.asset(
                    "assets/wm_sc_goods_detail_actionbar_global_cart_light.webp",
                    height: 36,
                  ),
                ),
              ),
            );
          },
        ),
      ),
    );
  }

  Widget _getListItem(BuildContext context, index, List<Map> data) {
    switch (index) {
      case 0:
        return const MainBackground();
      case 1:
        return const SearchKeywords();
      case 2:
        return Carousel();
      case 3:
        return const NavigationPanel();
      case 4:
        return const SpecialRecommendation();
      case 5:
        return const RestaurantAds();
      case 6:
          return FilterBar(key: Provider.of<ScrollState>(context).filterBarKey, isSnap: false,);
      default:
        int subIndex = index - 7;
        if (subIndex < data.length) {
          return RecommendedFoodItem(data: data[subIndex]);
        }
        if (subIndex == data.length) {
          return PullUpToRefreshAnimation();
        }
    }
    return null;
  }
}

class ScrollState extends ChangeNotifier {
  double scrollOffset = 0;
  double fabOffsetX = 0;
  double fabOpacity = 0.8;
  bool showFilterBar = false;
  double filterBarPaddingTop = 40;
  int deltaDarkness = 0;
  int opacity = 0;
  GlobalKey filterBarKey = GlobalKey();
  RestartableTimer _timer;

  ScrollState() {
    _timer = RestartableTimer(Duration(milliseconds: 400), () {
      fabOffsetX = 0;
      fabOpacity = 0.8;
      notifyListeners();
    });
  }

  void update(double newOffset, double paddingTop) {
    scrollOffset = newOffset;
    if (filterBarKey.currentContext != null) {
      var dy = (filterBarKey.currentContext.findRenderObject() as RenderBox)
          .localToGlobal(Offset.zero)
          .dy;
      var oldShowFilterBar = showFilterBar;
      var oldFilterBarPaddingTop = filterBarPaddingTop;
      if (dy <= 52 + paddingTop) {
        showFilterBar = true;
        var ratio = (52 + paddingTop - dy) / 40;
        if (ratio > 1) ratio = 1;
        filterBarPaddingTop = 40 - 40 * ratio;
      } else {
        filterBarPaddingTop = 40;
        showFilterBar = false;
      }
      if (oldShowFilterBar == showFilterBar && oldFilterBarPaddingTop == filterBarPaddingTop && oldShowFilterBar) return;
    } else {
      if (showFilterBar) return;
    }
    var oldOpacity = opacity;
    var oldDeltaDarkness = deltaDarkness;
    deltaDarkness = (scrollOffset > 0)
        ? ((scrollOffset / flexibleBarHeight > 1
                    ? 1
                    : (scrollOffset / flexibleBarHeight)) *
                20)
            .toInt()
        : 0;
    opacity = scrollOffset > 0
        ? ((scrollOffset / flexibleBarHeight > 1
        ? 1
        : (scrollOffset / flexibleBarHeight)) *
        255)
        .toInt()
        : 0;
    if (oldDeltaDarkness == deltaDarkness && oldOpacity == 1) {
      if (!showFilterBar) return;
      if (filterBarPaddingTop == 0) return;
    }

    notifyListeners();
  }

  void onScrollStart() {
    _timer.cancel();
    fabOpacity = 0.5;
    fabOffsetX = 40;
    notifyListeners();
  }

  void onScrollEnd() {
    _timer.reset();
  }
}
